#pragma once


//#include "precomp.hpp"
#include<opencv2/opencv.hpp>
#include <climits>
#include <iostream>
using namespace std;
using namespace cv;

namespace tcl_depth_image {

#define CV_OVERRIDE   override
#ifdef _MSC_VER
#   pragma warning(disable: 4512)
#endif

	typedef Vec<float, 1> Vec1f;
	typedef Vec<uchar, 1> Vec1b;

#ifndef SQR
#define SQR(a) ((a)*(a))
#endif

	template<typename JointVec, typename SrcVec, typename MaskVec>
	class JointBilateralFilter_8u : public ParallelLoopBody
	{
		Mat &joint, &src, &mask;
		Mat &dst;
		int radius, maxk;
		float scaleIndex;
		int *spaceOfs;
		float *spaceWeights, *expLUT;

	public:

		JointBilateralFilter_8u(Mat& joint_, Mat& src_, Mat& mask_, Mat& dst_, int radius_,
			int maxk_, int *spaceOfs_, float *spaceWeights_, float *expLUT_)
			:
			joint(joint_), src(src_), mask(mask_), dst(dst_), radius(radius_), maxk(maxk_),
			spaceOfs(spaceOfs_), spaceWeights(spaceWeights_), expLUT(expLUT_)
		{
			CV_DbgAssert(joint.type() == traits::Type<JointVec>::value && src.type() == dst.type() && src.type() == traits::Type<SrcVec>::value);
			CV_DbgAssert(joint.rows == src.rows && src.rows == dst.rows + 2 * radius);
			CV_DbgAssert(joint.cols == src.cols && src.cols == dst.cols + 2 * radius);
		}

		void operator () (const Range& range) const CV_OVERRIDE
		{
			typedef Vec<int, JointVec::channels> JointVeci;
			typedef Vec<float, SrcVec::channels> SrcVecf;
			typedef Vec<int, MaskVec::channels> MaskVeci;

			for (int i = radius + range.start; i < radius + range.end; i++)
			{
				for (int j = radius; j < src.cols - radius; j++)
				{
					JointVec *jointCenterPixPtr = joint.ptr<JointVec>(i) + j;
					SrcVec *srcCenterPixPtr = src.ptr<SrcVec>(i) + j;
					MaskVec *maskCenterpixptr = mask.ptr<MaskVec>(i) + j;

					JointVeci jointPix0 = JointVeci(*jointCenterPixPtr);
					SrcVecf srcSum = SrcVecf::all(0.0f);
					//SrcVecf srcPix0 = SrcVecf(*srcCenterPixPtr);
					MaskVeci maskPix0 = MaskVeci(*maskCenterpixptr);

					if (maskPix0[0] == 0)
					{
						dst.at<SrcVec>(i - radius, j - radius) = srcCenterPixPtr[0];
					}
					else
					{
						float wSum = 0.0f;

						for (int k = 0; k < maxk; k++)
						{
							uchar *jointPix = reinterpret_cast<uchar*>(jointCenterPixPtr + spaceOfs[k]);
							int alpha = 0;
							for (int cn = 0; cn < JointVec::channels; cn++)
								alpha += std::abs(jointPix0[cn] - (int)jointPix[cn]);

							float weight = 0.0;
							if (alpha < 10)
							{
								weight = 10 * spaceWeights[k] * expLUT[alpha];
							}
							else
							{
								weight = spaceWeights[k] * expLUT[alpha];
							}
							//float weight = spaceWeights[k] * expLUT[alpha];


							uchar *srcPix = reinterpret_cast<uchar*>(srcCenterPixPtr + spaceOfs[k]);
							for (int cn = 0; cn < SrcVec::channels; cn++)
								srcSum[cn] += weight*srcPix[cn];
							wSum += weight;

						}

						dst.at<SrcVec>(i - radius, j - radius) = SrcVec(srcSum / wSum);

					}


				}
			}
		}
	};

	void jointBilateralFilter_8u(Mat& joint, Mat& src, Mat& mask, Mat& dst, int radius, double sigmaColor, double sigmaSpace, int borderType)
	{
		CV_DbgAssert(joint.depth() == CV_8U && src.depth() == CV_8U && mask.depth());

		int d = 2 * radius + 1;
		int jCn = joint.channels();

		double gaussColorCoeff = -0.5 / (sigmaColor*sigmaColor);
		double gaussSpaceCoeff = -0.5 / (sigmaSpace*sigmaSpace);

		vector<float> expLUTv(jCn * 256);
		float *expLUT = &expLUTv[0];

		for (int i = 0; i < (int)expLUTv.size(); i++)
		{
			expLUT[i] = (float)std::exp(i * i * gaussColorCoeff);
		}

		Mat jointTemp, srcTemp, maskTemp;
		copyMakeBorder(joint, jointTemp, radius, radius, radius, radius, borderType);
		copyMakeBorder(src, srcTemp, radius, radius, radius, radius, borderType);
		copyMakeBorder(mask, maskTemp, radius, radius, radius, radius, BORDER_CONSTANT, cv::Scalar(0));
		size_t srcElemStep = srcTemp.step / srcTemp.elemSize();
		size_t jElemStep = jointTemp.step / jointTemp.elemSize();
		CV_Assert(srcElemStep == jElemStep);

		vector<float> spaceWeightsv(d*d);
		vector<int> spaceOfsJointv(d*d);
		float *spaceWeights = &spaceWeightsv[0];
		int *spaceOfsJoint = &spaceOfsJointv[0];

		int maxk = 0;
		for (int i = -radius; i <= radius; i += 4)
		{
			for (int j = -radius; j <= radius; j += 4)
			{
				double r2 = i*i + j*j;
				int r2_t = int(std::sqrt(r2));
				if (r2 > SQR(radius) || r2_t % 10 > 5)
					continue;

				spaceWeights[maxk] = (float)std::exp(r2 * gaussSpaceCoeff);
				spaceOfsJoint[maxk] = (int)(i*jElemStep + j);
				maxk++;
			}
		}
		//std::cout << maxk << std::endl;
		//double t1 = (double)cv::getTickCount();
		Range range(0, src.rows);

		if (joint.type() == CV_8UC3)
		{
			if (src.type() == CV_8UC1)
			{
				parallel_for_(range, JointBilateralFilter_8u<Vec3b, Vec1b, Vec1b>(jointTemp, srcTemp, maskTemp, dst, radius, maxk, spaceOfsJoint, spaceWeights, expLUT));
			}
		}
		//double t2 = (double)cv::getTickCount();
		//t2 = (t2 - t1) / (double)cv::getTickFrequency() * 1000;

		//std::cout << "*******part time:" << t2 << std::endl;
	}

	void jointBilateralFilter_(InputArray joint_, InputArray src_, InputArray mask_, OutputArray dst_, int d, double sigmaColor, double sigmaSpace, int borderType)
	{
		CV_Assert(!src_.empty());

		if (joint_.empty())
		{
			bilateralFilter(src_, dst_, d, sigmaColor, sigmaSpace, borderType);
			return;
		}

		Mat src = src_.getMat();
		Mat joint = joint_.getMat();
		Mat mask = mask_.getMat();

		if (src.data == joint.data)
		{
			bilateralFilter(src_, dst_, d, sigmaColor, sigmaSpace, borderType);
			return;
		}

		CV_Assert(src.size() == joint.size());
		CV_Assert(src.depth() == joint.depth() && (src.depth() == CV_8U || src.depth() == CV_32F));

		if (sigmaColor <= 0)
			sigmaColor = 1;
		if (sigmaSpace <= 0)
			sigmaSpace = 1;

		int radius;
		if (d <= 0)
			radius = cvRound(sigmaSpace*1.5);
		else
			radius = d / 2;
		radius = std::max(radius, 1);

		dst_.create(src.size(), src.type());
		Mat dst = dst_.getMat();

		if (dst.data == joint.data)
			joint = joint.clone();
		if (dst.data == src.data)
			src = src.clone();

		int jointCnNum = joint.channels();
		int srcCnNum = src.channels();

		if ((srcCnNum == 1 || srcCnNum == 3) && (jointCnNum == 1 || jointCnNum == 3))
		{
			if (joint.depth() == CV_8U)
			{
				jointBilateralFilter_8u(joint, src, mask, dst, radius, sigmaColor, sigmaSpace, borderType);
			}
			/*else
			{
				jointBilateralFilter_32f(joint, src, dst, radius, sigmaColor, sigmaSpace, borderType);
			}*/
		}
		else
		{
			CV_Error(Error::BadNumChannels, "Unsupported number of channels");
		}
	}


	//void calcMask(cv::Mat &disp, cv::Mat& disp_8u,cv::Mat& mask)
	//{
	//	disp.convertTo(disp_8u, CV_8U, 255 / (32*16.0));
	//	
	//	cv::Rect rect = cv::Rect(30, 30, 580, 430);
	//	cv::Mat dispImgRoi(cv::Size(disp.cols,disp.rows),CV_8UC1,cv::Scalar(0));
	//
	//	disp_8u(rect).copyTo(dispImgRoi);
	//
	//	cv::Mat xBorder, yBorder, xyBorder;
	//
	//	cv::Sobel(dispImgRoi, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
	//	cv::Sobel(dispImgRoi, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
	//
	//	cv::convertScaleAbs(xBorder, xBorder);
	//	cv::convertScaleAbs(yBorder, yBorder);
	//
	//	cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
	//
	//	double min = 0, max = 0;
	//	cv::minMaxLoc(disp, &min, &max, NULL, NULL);
	//
	//	for (int row = 0; row < xyBorder.rows; row++)
	//	{
	//		for (int col = 0; col < xyBorder.cols; col++)
	//		{
	//			if (xyBorder.at<uchar>(row, col) > 5)
	//			{
	//				double avg = 0;
	//				int num = 0;
	//				int x_beg = std::max(col + 30 - 3, 30), x_end = std::min(col + 30 + 3, 610);
	//				int y_beg = std::max(row + 30 - 3, 30), y_end = std::min(row + 30 + 3, 460);
	//				for (int y = y_beg; y < y_end; y++)
	//				{
	//					for (int x = x_beg; x < x_end; x++)
	//					{
	//						avg += disp_8u.at<uchar>(y, x);
	//						num++;
	//					}
	//				}
	//
	//				avg = avg / (double)num;
	//
	//				if (avg>(0.4*max))
	//					xyBorder.at<uchar>(row, col) = 0;
	//			}
	//
	//		}
	//	}
	//
	//	cv::threshold(xyBorder, xyBorder, 5, 255, cv::THRESH_BINARY);
	//	xyBorder.copyTo(mask(rect));
	//
	//	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(30, 30));
	//	cv::Mat element1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
	//	cv::Mat element2 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
	//	cv::dilate(mask, mask, element, cv::Point(-1, -1), 1);
	//	cv::erode(mask, mask, element1, cv::Point(-1, -1), 4);
	//	cv::erode(mask, mask, element2, cv::Point(-1, -1), 2);
	//	//cv::erode(mask, mask, element1, cv::Point(-1, -1), 1);
	//
	//}
	//
	//void calcMask_rgb(cv::Mat &disp, cv::Mat &disp_8u, cv::Mat &color, cv::Mat &mask)
	//{
	//	disp.convertTo(disp_8u, CV_8U, 255 / (32 * 16.0));
	//	cv::Mat gray;
	//	cv::cvtColor(color, gray, cv::COLOR_BGR2GRAY);
	//	cv::Mat xBorder, yBorder, xyBorder;
	//	cv::Sobel(gray, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
	//	cv::Sobel(gray, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
	//
	//	cv::convertScaleAbs(xBorder, xBorder);
	//	cv::convertScaleAbs(yBorder, yBorder);
	//
	//
	//	cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
	//	//cv::Mat xyBorder_gray;
	//	//cv::cvtColor(xyBorder, xyBorder_gray, cv::COLOR_BGR2GRAY);
	//
	//	//double max = 0, min = 0;
	//	//cv::minMaxLoc(xyBorder_gray, &min, &max);
	//
	//	//max = cvRound(max*0.7);
	//
	//	cv::threshold(xyBorder, mask, 100, 255, cv::THRESH_BINARY);
	//
	//	cv::Mat element = cv::getStructuringElement(MORPH_RECT, cv::Size(7, 7));
	//	cv::dilate(mask, mask, element, cv::Point(-1, -1), 1);
	//
	//}
	//
	//void calcMask_for_bm(cv::Mat &disp, cv::Mat& mask)
	//{
	//
	//	cv::Rect rect = cv::Rect(30, 30, 580, 430);
	//	cv::Mat dispImgRoi(cv::Size(disp.cols, disp.rows), CV_8UC1, cv::Scalar(0));
	//
	//	disp(rect).copyTo(dispImgRoi);
	//
	//	cv::Mat xBorder, yBorder, xyBorder;
	//
	//	cv::Sobel(dispImgRoi, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
	//	cv::Sobel(dispImgRoi, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
	//
	//	cv::convertScaleAbs(xBorder, xBorder);
	//	cv::convertScaleAbs(yBorder, yBorder);
	//
	//	cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
	//
	//	cv::threshold(xyBorder, xyBorder, 10, 255, cv::THRESH_BINARY);
	//	xyBorder.copyTo(mask(rect));
	//
	//	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));
	//	cv::dilate(mask, mask, element, cv::Point(-1, -1), 1);
	//
	//}

	void calcMask_for_bm_old(cv::Mat &disp, cv::Mat& mask)
	{

		cv::Mat xBorder, yBorder, xyBorder;
		cv::Sobel(disp, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
		cv::Sobel(disp, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
		cv::convertScaleAbs(xBorder, xBorder);
		cv::convertScaleAbs(yBorder, yBorder);
		cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
		cv::threshold(xyBorder, mask, 5, 255, cv::THRESH_BINARY);


		cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));//5
		cv::dilate(mask, mask, element, cv::Point(-1, -1), 2);

	}

	void adaptiveCalcMask(cv::Mat &disp, cv::Mat &mask)
	{
		int w = disp.cols, h = disp.rows;
		cv::Rect rt = cv::Rect(w / 2 - w / 8, h / 2 - h / 8, w / 4, h / 4);

		//meanStdDev
		cv::Scalar mean_roi = cv::mean(disp(rt));
		cv::Scalar mean_all = cv::mean(disp);

		int val_roi = mean_roi.val[0], val_all = mean_all.val[0];

		double k = val_all / (double)val_roi;

		int thresh = 0;

		if (k < 1.5)
			thresh = 80;
		else
		{
			thresh = (int)(1.3*val_roi);
			if (thresh < 35)
				thresh = 35;
		}

		//std::cout << "warming!!!: " << thresh << std::endl;



		cv::Mat thre_img(cv::Size(w, h), CV_8UC1, cv::Scalar(255));

		for (int i = 0; i < h; i++)
		{
			uchar* ptr_d = disp.ptr(i);
			uchar* ptr_b = thre_img.ptr(i);
			for (int j = 0; j < w; j++)
			{
				if (ptr_d[j] > thresh)
					ptr_b[j] = 0;
			}
		}


		cv::Mat element_ = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
		cv::erode(thre_img, thre_img, element_, cv::Point(-1, -1), 2);
		cv::dilate(thre_img, thre_img, element_, cv::Point(-1, -1), 2);

		cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
		cv::dilate(thre_img, thre_img, element, cv::Point(-1, -1), 1);

		//cv::imshow("mul", thre_img);
		cv::Mat mul;
		cv::threshold(thre_img, mul, 1, 1, cv::THRESH_BINARY);


		cv::Mat xBorder, yBorder, xyBorder;
		cv::Sobel(disp, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
		cv::Sobel(disp, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
		cv::convertScaleAbs(xBorder, xBorder);
		cv::convertScaleAbs(yBorder, yBorder);
		cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
		cv::threshold(xyBorder, mask, 5, 255, cv::THRESH_BINARY);


		cv::Mat element__ = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));//5
		cv::dilate(mask, mask, element__, cv::Point(-1, -1), 1);

		mask = mask.mul(mul);
		//cv::imshow("mask_", mask);
		int allCount = 816 * 612;
		//int maskCount = 816 * 612 * 0.1;
		//int maskCount_= 816 * 612 * 0.5;

		int count = cv::countNonZero(mask);
		if (count > allCount*0.5)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(21, 21));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.4)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(13, 13));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.3)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.2)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.1)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(13, 13));
			cv::dilate(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else //if (count < allCount*0.1)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(21, 21));
			cv::dilate(mask, mask, element_1, cv::Point(-1, -1), 1);
		}



	}

	void adaptiveCalcMask_(cv::Mat &disp, cv::Mat &mask, int thresh)
	{
		int w = disp.cols, h = disp.rows;
		//cv::Rect rt = cv::Rect(w / 2 - w / 8, h / 2 - h / 8, w / 4, h / 4);

		////meanStdDev
		//cv::Scalar mean_roi = cv::mean(disp(rt));
		//cv::Scalar mean_all = cv::mean(disp);

		//int val_roi = mean_roi.val[0], val_all = mean_all.val[0];

		//double k = val_all / (double)val_roi;

		//int thresh = 0;

		//if (k < 1.5)
		//	thresh = 80;
		//else
		//{
		//	thresh = (int)(1.3*val_roi);
		//	if (thresh < 35)
		//		thresh = 35;
		//}

		//std::cout << "warming!!!: " << thresh << std::endl;



		cv::Mat thre_img(cv::Size(w, h), CV_8UC1, cv::Scalar(255));

		for (int i = 0; i < h; i++)
		{
			uchar* ptr_d = disp.ptr(i);
			uchar* ptr_b = thre_img.ptr(i);
			for (int j = 0; j < w; j++)
			{
				if (ptr_d[j] > thresh)
					ptr_b[j] = 0;
			}
		}


		cv::Mat element_ = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
		cv::erode(thre_img, thre_img, element_, cv::Point(-1, -1), 2);
		cv::dilate(thre_img, thre_img, element_, cv::Point(-1, -1), 2);

		cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
		cv::dilate(thre_img, thre_img, element, cv::Point(-1, -1), 1);

		//cv::imshow("mul", thre_img);
		cv::Mat mul;
		cv::threshold(thre_img, mul, 1, 1, cv::THRESH_BINARY);


		cv::Mat xBorder, yBorder, xyBorder;
		cv::Sobel(disp, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
		cv::Sobel(disp, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
		cv::convertScaleAbs(xBorder, xBorder);
		cv::convertScaleAbs(yBorder, yBorder);
		cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
		cv::threshold(xyBorder, mask, 5, 255, cv::THRESH_BINARY);


		cv::Mat element__ = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));//5
		cv::dilate(mask, mask, element__, cv::Point(-1, -1), 1);

		mask = mask.mul(mul);
		//cv::imshow("mask_", mask);
		int allCount = 816 * 612;
		//int maskCount = 816 * 612 * 0.1;
		//int maskCount_= 816 * 612 * 0.5;

		int count = cv::countNonZero(mask);
		if (count > allCount*0.5)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(21, 21));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.4)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(13, 13));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.3)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.2)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));
			cv::erode(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else if (count > allCount*0.1)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(13, 13));
			cv::dilate(mask, mask, element_1, cv::Point(-1, -1), 1);
		}
		else //if (count < allCount*0.1)
		{
			cv::Mat element_1 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(21, 21));
			cv::dilate(mask, mask, element_1, cv::Point(-1, -1), 1);
		}



	}

	void calcMask_rgb(cv::Mat &color, cv::Mat &disp, cv::Mat &mask)
	{
		//
		//cv::Mat gray;
		//cv::cvtColor(color, gray, COLOR_BGR2GRAY);

		//cv::Mat xBorder, yBorder, xyBorder;
		//cv::Sobel(gray, xBorder, CV_16S, 1, 0, 3, 1.0, 0);
		//cv::Sobel(gray, yBorder, CV_16S, 0, 1, 3, 1.0, 0);
		//cv::convertScaleAbs(xBorder, xBorder);
		//cv::convertScaleAbs(yBorder, yBorder);
		//cv::addWeighted(xBorder, 0.5, yBorder, 0.5, 0, xyBorder);
		//


		//int w = disp.cols, h = disp.rows;

		//for (int i = 0; i < h; i++)
		//{
		//	uchar* ptr_d = disp.ptr(i);
		//	uchar* ptr_b = xyBorder.ptr(i);
		//	for (int j = 0; j < w; j++)
		//	{
		//		if (ptr_d[j] >120)//100
		//			ptr_b[j] = 0;
		//	}
		//}

		//cv::threshold(xyBorder, mask, 0, 255, cv::THRESH_BINARY);

		int w = disp.cols, h = disp.rows;
		cv::Mat xyBorder(cv::Size(w, h), CV_8UC1, cv::Scalar(255));

		for (int i = 0; i < h; i++)
		{
			uchar* ptr_d = disp.ptr(i);
			uchar* ptr_b = xyBorder.ptr(i);
			for (int j = 0; j < w; j++)
			{
				if (ptr_d[j] > 80)//100//0330:85
					ptr_b[j] = 0;
			}
		}
		//cv::imshow("xyboder", xyBorder);

		cv::Mat element_ = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
		cv::erode(xyBorder, xyBorder, element_, cv::Point(-1, -1), 2);
		cv::dilate(xyBorder, xyBorder, element_, cv::Point(-1, -1), 2);

		cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
		cv::dilate(xyBorder, xyBorder, element, cv::Point(-1, -1), 1);

		cv::threshold(xyBorder, mask, 1, 1, cv::THRESH_BINARY);
	}

};
